/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */
package jp.ize.ux.components;

// {{{ imports
import jp.ize.ux.UXObject;
import jp.ize.ux.UXController;
import jp.ize.ux.UXInteraction;
import jp.ize.ux.acts.Act;
import jp.ize.ux.states.UXBasicState;
import jp.ize.ux.components.UXComponent;
import jp.ize.ux.components.UXComponentResource;
import jp.ize.ux.components.themes.basic.UXProgressBarResource;
import jp.ize.ux.interactions.UXGeneralInteraction;
import jp.ize.ux.geom.UXSize;
import jp.ize.ux.utils.UXRange;
import flash.events.Event;
// }}}
// {{{ typedef TProgressBarResources
typedef TProgressBarResources =
{
	background:UXComponentResource,
	track:UXComponentResource,
	bar:UXComponentResource
}
// }}}
// {{{ class UXProgressBarAct extends Act
/**
 * UXProgressBarAct クラス<br>
 * UXProgressBarのアクションです。
 */
class UXProgressBarAct extends Act
{
	// {{{ public function progress() : UXProgressBarState -> Void
	/**
	 * 進捗状況を画面に反映させるデフォルトアクションです。
	 */
	public function progress() : UXProgressBarState -> Void
	{
		return function( s : UXProgressBarState ) {
			s.bar.width = s.progress * s.barWidth;
		}
	}
	// }}}
	// {{{ public function enable() : UXProgressBarState -> Void
	/**
	 * 有効にした時のデフォルトアクションです。
	 */
	public function enable() : UXProgressBarState -> Void
	{
		return function( s : UXProgressBarState ) {
			s.background.normal();
			s.track.normal();
			s.bar.normal();
		}
	}
	// }}}
	// {{{ public function disable() : UXProgressBarState -> Void
	/**
	 * 無効にした時のデフォルトアクションです。
	 */
	public function disable() : UXProgressBarState -> Void
	{
		return function( s : UXProgressBarState ) {
			s.background.disabled();
			s.track.disabled();
			s.bar.disabled();
		}
	}
	// }}}
	// {{{ public function show() : UXProgressBarState -> Void
	/**
	 * 表示状態になった時のデフォルトアクションです。
	 */
	public function show() : UXProgressBarState -> Void
	{
		return function( s : UXProgressBarState ) {
			s.background.visible = true;
			s.track.visible = true;
			s.bar.visible = true;
		}
	}
	// }}}
	// {{{ public function hide() : UXProgressBarState -> Void
	/**
	 * 非表示状態になった時のデフォルトアクションです。
	 */
	public function hide() : UXProgressBarState -> Void
	{
		return function( s : UXProgressBarState ) {
			s.background.visible = false;
			s.track.visible = false;
			s.bar.visible = false;
		}
	}
	// }}}
}
// }}}
// {{{ class UXProgressBarState extends UXBasicState
/**
 * UXProgressBarState クラス<br>
 * UXProgressBarの現在の状態を表すクラスです。
 */
class UXProgressBarState extends UXBasicState
{
	// {{{ public var background( default, default ) : UXComponentResource
	/**
	 * プログレスバーの描画に使用するリソースです。
	 */
	public var background( default, default ) : UXComponentResource;
	// }}}
	// {{{ public var track(default, default) : UXComponentResource
	/**
	 * プログレスバートラック(バーの背景)です。
	 */
	public var track(default, default) : UXComponentResource;
	// }}}
	// {{{ public var bar(default, default) : UXComponentResource
	/**
	 * プログレスバーです。
	 */
	public var bar(default, default) : UXComponentResource;
	// }}}
	// {{{ public var range( default, default ) : UXRange
	/**
	 * 進捗状況の最大値、最小値です。
	 * デフォルトでは 0, 1 です。
	 */
	public var range( default, default ) : UXRange;
	// }}}
	// {{{ public var progress( default, default ) : Float
	/**
	 * 進捗状況です。
	 * range の範囲内である必要があります。
	 */
	public var progress( default, default ) : Float;
	// }}}
	// {{{ public var barWidth( default, default ) : Float
	/**
	 * bar の 幅を指定します。
	 */
	public var barWidth( default, default ) : Float;
	// }}}
	// {{{ public var acts(default, null) : UXProgressBarAct
	/**
	 * デフォルトの動きです。
	 */
	public var acts(default, null) : UXProgressBarAct;
	// }}}
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super();
		range = new UXRange(0.0,1.0);
		acts  = new UXProgressBarAct();
	}

	// }}}
}
// }}}

// {{{ class UXProgressBar extends UXComponent<UXProgressBarState>
/** 
 * UXProgressBar クラス<br>
 * ロード中のコンテンツの進捗状況を表示します。
 * ProgressBar コンポーネントは、プログレスバートラック(バーの背景)と完了したバーによって構成されます。<br>
 *
 * @author		iZE Co., Ltd.<br>
 * @version		$Id: UXProgressBar.hx 20 2009-02-04 08:23:19Z yimai.v $<br>
 */
class UXProgressBar extends UXComponent<UXProgressBarState>
{
	// {{{ properties

	public var watchHandler : Dynamic -> Void;

	// }}}
	// {{{ public function new( ?range:UXRange, ?size:UXSize, ?res:TProgressBarResources )
	/**
	 * コンストラクタです。
	 *
	 * @param range: プログレスバーの取る数値範囲です。省略可能です。指定しない場合は、0.0～1.0になります。
	 * @param size: バーのサイズです。
	 * @param res: デザイン・リソースです。
	 */
	public function new( ?range:UXRange, ?size:UXSize, ?res:TProgressBarResources )
	{
		if ( res==null ) {
			res = {
				background : UXProgressBarResource.getBackground(size),
				track      : UXProgressBarResource.getTrack(size),
				bar        : UXProgressBarResource.getBar(size)
			}
		}
		state = new UXProgressBarState();
		state.target = this;
		state.background = res.background;
		state.track      = res.track;
		state.bar        = res.bar;
		state.barWidth   = res.bar.width;
		state.bar.width  = 0;
		if ( range!=null ) {
			state.range = range;
		}
		ctrl = new UXController<UXProgressBarState>( state );
		ctrl.addInteraction(new UXProgressBarProgressInteraction());
		super(ctrl);
		ctrl.getInteraction("Progress").addAct(state.acts.progress());
		addUXChild(res.background);
		addUXChild(res.track);
		addUXChild(res.bar);
	}
	// }}}
	// {{{ public function attachResource() : Void
	/**
	 * グローバルなリソースをresourceプロパティに取得する関数です。
	 */
	public function attachResource() : Void
	{
	}
	// }}}
	// {{{ public function startWatch( handler:Void->Float ) : Void
	/**
	 * ハンドラーを登録して、プログレスバーの進捗を更新します。
	 * ハンドラーは、Float にて 0から1 の値を返す関数です。
	 */
	public function startWatch( handler:Void->Float ) : Void
	{
		var me = this;
		watchHandler = function(e) {
			me.state.progress = handler();
			Act.exec(me.state.acts.progress(),me.state);
		}
		addUXEventListener( Event.ENTER_FRAME, watchHandler );
	}
	// }}}
	// {{{ public function stopWatch() : Void
	/**
	 * 登録したハンドラーでの監視を停止します。
	 */
	public function stopWatch() : Void
	{
		removeUXEventListener( Event.ENTER_FRAME, watchHandler );
	}
	// }}}
	// {{{ public function update( updator : UXProgressBarState -> Void ) : Void
	/**
	 * このコンポーネントの状態を直接変更するメソッドです。状態のどんな操作も可能になるので、
	 * このメソッドの使用には注意が必要です。
	 */
	public function update( updator : UXProgressBarState -> Void ) : Void
	{
		updator( state );
	}
	// }}}
}
// }}}

// {{{ class UXProgressBarProgressInteraction extends UXGeneralInteraction<UXProgressBarState>
/**
 * UXProgressBarProgressInteraction クラス<br>
 * 進捗状況に対応するデフォルトインタラクションです。
 */
class UXProgressBarProgressInteraction extends UXGeneralInteraction<UXProgressBarState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("Progress");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
